package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.collection.CollectionUtil;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.common.cache.GuiGuCache;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.events.Event;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@SuppressWarnings({"all"})
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;

    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;

    @Autowired
    private BaseCategoryViewMapper baseCategoryViewMapper;

    @Autowired
    private BaseAttributeMapper baseAttributeMapper;

    /**
     * 查询所有分类（1、2、3级分类）
     *
     * @return
     */
    @Override
    public List<JSONObject> getBaseCategoryList() {
        //创建封装数据集合
        List<JSONObject> categoryList = new ArrayList<>();

        //获取所有分类数据
        List<BaseCategoryView> categoryViewList = baseCategoryViewMapper.selectList(null);
        //判断
        if (CollectionUtil.isNotEmpty(categoryViewList)) {
            //分组获取一级分类数据
            Map<Long, List<BaseCategoryView>> category1MapList =
                    categoryViewList.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));
            //key:cateogry1Id value:
            //遍历方式
            for (Map.Entry<Long, List<BaseCategoryView>> entry1 : category1MapList.entrySet()) {
                //创建一级分类封装对象
                JSONObject object1 = new JSONObject();

                //获取一级分类id
                Long category1Id = entry1.getKey();
                object1.put("categoryId", category1Id);
                //获取一级分类name
                List<BaseCategoryView> category2List = entry1.getValue();
                String category1Name = category2List.get(0).getCategory1Name();
                object1.put("categoryName", category1Name);
                //获取一级分类所属的二级分类集合
                List<JSONObject> categoryList2 = new ArrayList<>();
                //对象二级分类分组
                Map<Long, List<BaseCategoryView>> category2MapList =
                        category2List.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
                //处理二级分类数据
                for (Map.Entry<Long, List<BaseCategoryView>> entry2 : category2MapList.entrySet()) {
                    //创建二级分类封装对象
                    JSONObject object2 = new JSONObject();
                    //获取二级分类id
                    Long category2Id = entry2.getKey();
                    object2.put("categoryId", category2Id);
                    //获取二级分类name
                    List<BaseCategoryView> category3List = entry2.getValue();
                    String category2Name = category3List.get(0).getCategory2Name();
                    object2.put("categoryName", category2Name);
                    //获取二级分类所属的三级分类集合
                    List<JSONObject> categoryList3 = new ArrayList<>();
                    //处理三级分类
                    for (BaseCategoryView baseCategoryView : category3List) {
                        //创建三级分类封装对象
                        JSONObject object3 = new JSONObject();
                        Long category3Id = baseCategoryView.getCategory3Id();
                        String category3Name = baseCategoryView.getCategory3Name();
                        object3.put("categoryId", category3Id);
                        object3.put("categoryName", category3Name);
                        categoryList3.add(object3);
                    }

                    object2.put("categoryChild", categoryList3);
                    //封装二级分类数据
                    categoryList2.add(object2);
                }


                //封装二级分类集合
                object1.put("categoryChild", categoryList2);

                categoryList.add(object1);
            }
        }
        return categoryList;
    }

    /**
     * 根据一级分类Id获取分类属性（标签）列表
     *
     * @param category1Id
     * @return 两种方案：
     * 第一种：通用mapper
     * 第二种：自定义sql (采用)
     */
    @Override
    public List<BaseAttribute> findAttribute(Long category1Id) {
        return baseAttributeMapper.findAttribute(category1Id);
    }

    @Override
    @GuiGuCache(prefix="categoryViewBy3Id:")
    public BaseCategoryView getCategoryView(Long category3Id) {
        return baseCategoryViewMapper.selectById(category3Id);
    }

    @Override
    public List<BaseCategory3> findTopBaseCategory3(Long category1Id) {
        //1.根据一级分类ID查询二级分类ID集合
        LambdaQueryWrapper<BaseCategory2> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //判断
        lambdaQueryWrapper.eq(BaseCategory2::getCategory1Id, category1Id);
        //选择出来
        lambdaQueryWrapper.select(BaseCategory2::getId);
        //以集合的方式提取出来
        List<BaseCategory2> baseCategory2s = baseCategory2Mapper.selectList(lambdaQueryWrapper);
        //2.根据二级分类ID查询三级分类列表（if判断是否为空）
        if (CollectionUtil.isNotEmpty(baseCategory2s)) {
            //使用流的方式将baseCategory2中的所有的属性值提取出来
            List<Long> baseCategory2 = baseCategory2s.stream().map(BaseCategory2::getId).collect(Collectors.toList());
            //使用lambda表达式的方式，是一个查询包装类
            LambdaQueryWrapper<BaseCategory3> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            //包含所有要匹配的值
            lambdaQueryWrapper1.in(BaseCategory3::getCategory2Id, baseCategory2);
            //升序
            lambdaQueryWrapper1.orderByAsc(BaseCategory3::getId);
            //获取七个
            lambdaQueryWrapper1.last("limit 7");
            //返回最后需要的数据
            return baseCategory3Mapper.selectList(lambdaQueryWrapper1);
        }
        return null;
    }


    /**
     * f根据一级id获取二级以及二级下面的三级分类
     *
     * @param category1Id
     * @return
     */

    @Override
    public JSONObject getBaseCategoryList1Id(Long category1Id) {

        //获取一级id中的信息和分类
        BaseCategory1 baseCategory1 = baseCategory1Mapper.selectById(category1Id);
        //构建一级分类对象
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("categoryId", baseCategory1.getId());
        jsonObject.put("categoryName", baseCategory1.getName());

        //通过一级id获取二级的信息和分类
        LambdaQueryWrapper<BaseCategory2> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BaseCategory2::getCategory1Id, baseCategory1.getId());
        List<BaseCategory2> baseCategory2s = baseCategory2Mapper.selectList(lambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(baseCategory2s)) {
            List<JSONObject> collect1 = baseCategory2s.stream().map(baseCategory2 -> {
                JSONObject jsonObject2 = new JSONObject();
                jsonObject2.put("categoryId", baseCategory2.getId());
                jsonObject2.put("categoryName", baseCategory2.getName());

                //根据二级获得三级的信息和分类
                LambdaQueryWrapper<BaseCategory3> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                lambdaQueryWrapper1.eq(BaseCategory3::getCategory2Id, baseCategory2.getId());
                List<BaseCategory3> baseCategory3s = baseCategory3Mapper.selectList(lambdaQueryWrapper1);
                if (CollectionUtil.isNotEmpty(baseCategory3s)) {
                    List<JSONObject> collect = baseCategory3s.stream().map(baseCategory3 -> {
                        JSONObject jsonObject3 = new JSONObject();
                        jsonObject3.put("categoryId", baseCategory3.getId());
                        jsonObject3.put("categoryName", baseCategory3.getName());
                        return jsonObject3;
                    }).collect(Collectors.toList());
                    jsonObject2.put("categoryChild", collect);
                }
                return jsonObject2;
            }).collect(Collectors.toList());
            jsonObject.put("categoryChild", collect1);
        }
        return jsonObject;
    }
}